// Promise 基本示例

// const promise = new Promise(function (resolve, reject) {
//   // 兑现承诺

//   // resolve(100)  // 承诺达成

//   reject(new Error('promise rejected')) // 承诺失败
// })

// promise.then(function (value) {
//   console.log('resolved', value)
// }, function (error) {
//   console.log('rejected', error)
// })

// console.log('end')



// Promise 链式调用

function ajax(url) {
  return new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    xhr.responseType = 'json'
    xhr.onload = function () {
      if (this.status === 200) {
        resolve(this.response)
      } else {
        reject(new Error(this.statusText))
      }
    }
    xhr.send()
  })
}


// ajax('/api/users.json').then(
//     function onFulfilled(value) {
//         console.log('onFulfilled', value)
//     },
//     function onRejected(error) {
//         console.log('onRejected', error)
//     }
// )


// ajax('/api/users.json')
//     .then(function onFulfilled(value) {
//         console.log('onFulfilled', value)
//     })
//     .catch(function onRejected(error) {
//         console.log('onRejected', error)
//     })


// Promise 并行执行

// // Promise.all 返回一个全新的Promise
// var promise = Promise.all([
//   ajax('/api/user.json'),
//   ajax('api/posts.json')
// ])
// // 所有的Promise完成，全新的promise才会完成
// // 所以的异步任务都成功，promise才成功
// // 只要有一个异步任务失败，promise就失败
// promise.then(function (values) {
//   // 接收的是数组，包含每个异步任务执行的结果
//   console.log(values)
// }).catch(function (error) {
//   console.log(error)
// })


// const request = ajax('/api/posts.json')
// const timeout = new Promise((resolve, reject => {
//   setTimeout(() => reject(new Error('timeout')), 500)
// }))

// // Promise.race()将多个异步任务组合后返回一个新的promise对象
// // 多个异步任务中只要有一个完成（成功或失败），新的promise对象就完成了
// // 这里如果request请求在500毫秒内请求成功，就返回成功，使用.then方法
// // 如果500毫秒请求没有返回结果，就会reject一个错误，走到catch
// Promise.race([require, timeout])
//   .then(value => {
//     console.log(value)
//   })
//   .catch(error => {
//     console.log(error)
//   })





// 微任务
// console.log('global start')

// setTimeout(() => {
//   console.log('setTimeout')
// }, 0)

// Promise.resolve()
//   .then(() => {
//     console.log('promise')
//   })
//   .then(() => {
//     console.log('promise 2')
//   })
//   .then(() => {
//     console.log('promise 3')
//   })
// console.log('global end')

// global start
// global end
// promise
// promise 2
// promise 3
// setTimeout




// 生成器函数回顾
// // 比普通的函数多了一个 *
// function * foo() {
//   console.log('start')

//   // 用 yield 返回一个值，next 方法返回的就是这个值
//   // yield 不会结束生成器的执行，只是 暂停
//   // 如果next方法传入一个参数，会作为上一个yield 的返回值
//   // yield 'foo'
//   // const res = yield 'foo'
//   // console.log(res) // bar

//   try {
//     const res = yield 'foo'
//     console.log(res) // bar
//   } catch (e) {
//     console.log(e)
//   }
// }

// // 调用生成器并不会立即执行，而是得到一个生成器对象
// const generator = foo()

// // 调用next方法，函数体才会执行
// const result = generator.next()
// // 返回结果中有一个done属性，表示生成器是否一起执行完了
// console.log(result)  //{value: "foo", done: false}

// // 再一次调用next方法时，会从 yield 位置开始执行
// // generator.next('bar')

// // 如果调用生成器的throw方法，也会继续往下执行，但是它会抛出一个异常
// // 在生成器内部使用try{}catch(){}语句来接收异常
// generator.throw(new Error('Generator error'))




// function* main() {
//   try {
//     const users = yield ajax(url1)
//     console.log(users)

//     const posts = yield ajax(url2)
//     console.log(posts)
//   } catch (e) {
//     console.log(e)
//   }
// }
// function co(generator) {
//   const g = generator()

//   function handleResult(result) {
//     if (result.done) return
//     result.value.then(data => {
//       handleResult(g.next(data))
//     }, error => {
//       g.throw(error)
//     })
//   }

//   handleResult(g.next())
// }

// co(main)



// Async / Await
// // 将生成器的 * 改为 async ，yield 改为 await 
// async function main() {
//   try {
//     const users = await ajax(url1)
//     console.log(users)

//     const posts = await ajax(url2)
//     console.log(posts)
//   } catch (e) {
//     console.log(e)
//   }
// }
// // 直接调用，不需要 co
// // async 函数返回一个promise对象
// const promise = main()
// promise.then(() => {
//   console.log('all completed')
// })


Promise.any([
  ajax('111'),
  ajax('222')
]).then((value) => {
  console.log(value)
}).catch(err => {
  console.log(err)
})
